from django.db import transaction

from rest_framework import status, mixins
from rest_framework.response import Response
from rest_framework.settings import APISettings, IMPORT_STRINGS, DEFAULTS
from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet

from py_web.common.auth.MyAuth import MyAuth
from py_web.common.auth.SecurityUtils import isAdmin
from py_web.security.SecuritySerialization import UserRolesSerializer, RoleSerializer, UserSerializer
from py_web.security.models import UserRole, Role, User
from py_web.security.views import logger
from py_web.user.Filter import UserFilter

from utils.Page import MyPageNumberPagination
from utils.StrUtil import isNotEmpty

api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)


# 利用viewset构建基础增删改查查 用户表
class UserView(MyAuth,
               mixins.CreateModelMixin,
               mixins.UpdateModelMixin,
               mixins.DestroyModelMixin,
               GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    # 分页
    pagination_class = MyPageNumberPagination
    # 过滤器
    filterset_class = UserFilter

    """
        List a queryset.
        """

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page:list = self.paginate_queryset(queryset)
        newPage:list=[]
        # 过滤被逻辑删除的数据
        if isNotEmpty(page):
            for po in page:
                if not po.is_active:
                    continue
                newPage.append(po)



        if newPage is not None:
            serializer = self.get_serializer(newPage, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)

        return Response(serializer.data)

    # 根据id查询单个数据
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        # 过滤被逻辑删除的数据
        if isNotEmpty(instance):
            for po in instance:
                if not po.is_active:
                    instance.remove(po)
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_200_OK, headers=headers)

    def perform_create(self, serializer):
        serializer.save()




# 修改用户状态，状态限制是否可以登录
class UpdateUserStatusView(MyAuth, APIView):

    @transaction.atomic
    def put(self, request):
        if not isAdmin(request.user.pk):
            return Response("没权限", status=status.HTTP_401_UNAUTHORIZED)

        id = request.data['data']['id']

        if id is 1:
            return Response("不能修改admin", status=status.HTTP_401_UNAUTHORIZED)

        status2 = request.data['data']['status']

        res = User.objects.filter(id=id).update(status=status2)
        if res is 1:
            return Response("修改成功", status=status.HTTP_200_OK)
        else:
            return Response("修改失败", status=status.HTTP_400_BAD_REQUEST)


# 删除用户
class DeleteUserView(MyAuth, APIView):

    @transaction.atomic
    def delete(self, request):
        if not isAdmin(request.user.pk):
            return Response("没权限", status=status.HTTP_401_UNAUTHORIZED)

        ids: list[int] = request.data['ids']

        res = list(filter(lambda x: x == 1, ids))
        if len(res) is not 0:
            return Response("不能删除admin", status=status.HTTP_401_UNAUTHORIZED)

        user = User.objects.filter(id__in=ids)

        # 用户表逻辑删除
        for po in user:
            data = {
                "username": po.username,
                "id": po.id,
                "is_active": False,
                "password": po.password
            }
            serialize = UserSerializer(instance=po, data=data)
            try:
                serialize.is_valid(raise_exception=True)
            except Exception as e:
                logger.error(f"逻辑删除用户信息失败：{e},{serialize.errors}")
                return Response(serialize.errors, status=status.HTTP_400_BAD_REQUEST)

            serialize.save()

        # 删除角色关联关系
        userRole = UserRole.objects.filter(userId__in=ids)
        if userRole:
            userRole.delete()

        return Response("success", status=status.HTTP_200_OK)


# 根据用户id查询对应的角色信息
class GetRoleByUserId(MyAuth, APIView):

    def get(self, request, pk):
        if not isAdmin(request.user.pk):
            return Response("没权限", status=status.HTTP_401_UNAUTHORIZED)

        roles = UserRole.objects.filter(userId=pk)
        serializer = UserRolesSerializer(roles, many=True).data
        if serializer is None and len(roles) is 0:
            return Response("没数据", status=status.HTTP_302_FOUND)

        roleIds = []
        for serializ in serializer:
            roleIds.append(serializ['roleId'])

        roles = Role.objects.filter(roleId__in=roleIds)
        return Response(RoleSerializer(roles, many=True).data, status=status.HTTP_200_OK)


# 修改用户权限
class UpdateUserRole(MyAuth, APIView):

    @transaction.atomic
    def put(self, request):
        if not isAdmin(request.user.pk):
            return Response("没权限", status=status.HTTP_401_UNAUTHORIZED)

        userId = request.data['userId']
        newRoleIds: list = request.data['roleIds']
        if isAdmin(userId):
            return Response("不能修改admin", status=status.HTTP_401_UNAUTHORIZED)

        # 主要是修改用户角色中间表
        # 不管逻辑删除的一些数据，不会冲突。逻辑删除的数据一般定期直接删除
        userRole = UserRole.objects.filter(userId=userId)
        datas = UserRolesSerializer(instance=userRole, many=True).data
        oldRoleIds = []
        if datas:
            for data in datas:
                oldRoleIds.append(data.get('roleId'))

        # 求旧的补差集 多了就删除
        differences = list(set(oldRoleIds).difference(set(newRoleIds)))
        # 旧的，新的列表里面没有的  需要删除的值
        if isNotEmpty(differences):
            UserRole.objects.filter(userId=userId, roleId__in=differences).delete()

        # 求新的补差集,旧列表里面没有 多了就新增 相同的值不动
        differences = list(set(newRoleIds).difference(set(oldRoleIds)))
        if isNotEmpty(differences):
            for difference in differences:
                po = {
                    "roleId": difference,
                    "userId": userId,
                    "is_del": 0,
                }
                saveSerializer = UserRolesSerializer(data=po)
                saveSerializer.is_valid(raise_exception=True)
                saveSerializer.save()

        return Response("修改成功", status=status.HTTP_200_OK)
